home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Core / Includes / UClassDesc.h < prev    next >
Encoding:
Text File  |  1996-04-03  |  11.7 KB  |  317 lines  |  [TEXT/MPS ]

  1. // UClassDesc.h
  2. // Copyright Â© 1984-96 by Apple Computer, Inc. All rights reserved.
  3.  
  4.  
  5. #ifndef __UCLASSDESC__
  6. #define __UCLASSDESC__
  7.  
  8. // MacApp
  9.  
  10. #ifndef __MACAPPTYPES__
  11. #include "MacAppTypes.h"
  12. #endif
  13.  
  14. #ifndef __PASCALSTRING__
  15. #include "PascalString.h"
  16. #endif
  17.  
  18. // Toolbox
  19.  
  20. #ifndef __TYPES__
  21. #include <Types.h>
  22. #endif
  23.  
  24. // ANSI
  25.  
  26. #ifndef __STDDEF__
  27. #include <stddef.h>
  28. #endif
  29.  
  30. //----------------------------------------------------------------------------------------
  31. // Forward class declarations
  32. //----------------------------------------------------------------------------------------
  33.  
  34. class TClassDescListByName;
  35. class TClassDescListByID;
  36. class TClassDescSignatureList;
  37. class ClassDesc;
  38.  
  39. #ifndef qMultipleInheritance
  40. #define qMultipleInheritance TRUE
  41. #endif
  42.  
  43. //----------------------------------------------------------------------------------------
  44. // ClassID: A short, to minimize the amount of global space used by the type information.
  45. // ClassName: Returned by ClassDesc::GetClassName(). Internally we store class name as a
  46. //              c-string. It saves space.
  47. //----------------------------------------------------------------------------------------
  48.  
  49. typedef unsigned short ClassID;
  50. typedef CStr255 ClassName;
  51. typedef long ArrayIndex;
  52.  
  53.  
  54. //----------------------------------------------------------------------------------------
  55. // Some constants
  56. //----------------------------------------------------------------------------------------
  57.  
  58. const ClassID kNilClass = 0;
  59.  
  60.  
  61. //----------------------------------------------------------------------------------------
  62. // CLASS ClassDesc
  63. //----------------------------------------------------------------------------------------
  64.  
  65. typedef void * (* ConstructorProcPtr)();
  66.  
  67. class CClassIterator;
  68.  
  69. class ClassDesc;
  70. typedef const ClassDesc* MA_ClassReference;
  71.  
  72. #if qTheDebugger && PRAGMA_ALIGN_SUPPORTED
  73. #pragma options align=mac68k                            // TheDebugger looks at these
  74. #endif
  75.  
  76. class ClassDesc
  77. {
  78.     friend CClassIterator;                                // All Class iterator
  79.     
  80. public:
  81.     ClassDesc(const char* className, size_t classSize,
  82.               MA_ClassReference const *ancestors,
  83.               const ptrdiff_t *const offsets);
  84.                             
  85.     void* Call_DefaultConstructor() const;
  86.         // Return a new instance of the class. 
  87.     
  88.     ArrayIndex CountBaseClasses() const;
  89.         // Return a count of the number of ancestors. 
  90.     
  91.     void* DynamicCast(const void* p, MA_ClassReference pointersClass,
  92.                       MA_ClassReference aBaseClass) const;
  93.         // Returns nonzero pointer if p!=0 and DescendsFrom(aBaseClass), otherwise return 0.
  94.     
  95.     inline void GetClassName(ClassName& clName) const
  96.     { clName = fClassName; }
  97.         // Return a copy of the class name. 
  98.  
  99.     inline const char* GetClassName() const
  100.     { return fClassName; }
  101.         // Return a pointer to the class name. 
  102.     
  103.     inline ClassID GetClassID() const
  104.     { return fClassID; }
  105.         // Return the class ID. 
  106.     
  107.     inline void SetClassID(ClassID theClassID)
  108.     { fClassID = theClassID; }
  109.         // Allow setting the class ID (used by Jasik's debugger). 
  110.     
  111.     inline const size_t GetClassSize() const
  112.     { return fClassSize; }
  113.         // Returns the size of instances of the class. 
  114.     
  115.     MA_ClassReference GetBaseClass(ArrayIndex index = 1) const;
  116.         // Return a reference to the class info for an ancestor class. 
  117.     
  118.     inline MA_ClassReference GetNextClassDesc() const
  119.     { return fNextClassDesc; }
  120.         // Return a reference to the next class info record (not in any
  121.         // particular order). 
  122.     
  123.     IDType GetSignature() const;
  124.         // Looks up the signature used for creating this class. 
  125.     
  126.     Boolean DescendsFrom(MA_ClassReference theClass, Boolean directDescendant = FALSE) const;
  127.         // Return true if the class is or inherits from class represented by theClass. 
  128.         // Note, usage is: this->DescendsFrom(theClass). See also MA_MEMBER. 
  129.     
  130.     inline void RegisterClass(ConstructorProcPtr constructor)
  131.     { fDefaultConstructor = constructor; }
  132.         // Register a function that creates an instance of this class. 
  133.         // See MA_REGISTER_CLASS. 
  134.     
  135.     void RegisterSignature(IDType signature);
  136.         // Specify a signature for efficiently creating instances of this class
  137.         // from streams. See MA_REGISTER_SIGNATURE. 
  138.  
  139.   private:
  140.     Boolean OffsetToBase(MA_ClassReference aBaseClass, ptrdiff_t &offset) const;
  141.         // 
  142.  
  143.     //----------------------------------------------------------------------------------------
  144.     // static member functions
  145.     //----------------------------------------------------------------------------------------
  146. public:
  147.     static void InitUClassDesc();
  148.     
  149.     static Boolean IsValidClassID(ClassID classID);
  150.     
  151.     static void* NewByClassID(ClassID classID);
  152.     static void* NewByClassName(const ClassName& className);
  153.     static void* NewBySignature(IDType signature);
  154.     
  155.     static MA_ClassReference GetClassDescFromClassID(ClassID classID);
  156.     static MA_ClassReference GetClassDescFromClassName(const ClassName& className);
  157.     static MA_ClassReference GetClassDescFromSignature(IDType signature);
  158.     
  159.     inline static void CallRegisterClass(MA_ClassReference classDesc, ConstructorProcPtr constructor)
  160.     { ((ClassDesc*) classDesc)->RegisterClass(constructor); }
  161.  
  162.     inline static void CallRegisterSignature(MA_ClassReference classDesc, IDType signature)
  163.     { ((ClassDesc*) classDesc)->RegisterSignature(signature); }    
  164.  
  165.     //----------------------------------------------------------------------------------------
  166.     // data members
  167.     //----------------------------------------------------------------------------------------
  168. private:
  169.     const char* fClassName;                                // Class name
  170.     size_t fClassSize;                                    // Class size
  171.     MA_ClassReference const *fAncestors;                // ClassInfo for ancestors of the class.
  172.                                                         // Pointer to array of const pointers to ClassDesc
  173.     const ptrdiff_t *const fAncestorOffsets;            // Object pointer offsets for ancestors of the class. 
  174.  
  175.     MA_ClassReference fNextClassDesc;                    // Link to next ClassDesc in list of all ClassDesc.
  176.     ClassID fClassID;                                    // Unique identifying class ID.
  177.  
  178.     ConstructorProcPtr fDefaultConstructor;                // Default constructor for this class
  179.     
  180.     //----------------------------------------------------------------------------------------
  181.     // static data members
  182.     //----------------------------------------------------------------------------------------
  183. public:
  184.     // fgClassDescList needs to be public to satisfy a bug with Symantec's SCpp where
  185.     // it fails to correctly deal with friend classes…
  186.     static ClassDesc* fgClassDescList;                    // Head of linked list of
  187.                                                         // ClassDesc, created at static
  188.                                                         // initialization time.
  189.  
  190. private:
  191.     static TClassDescListByName* fgClassDescListByName;    // List of ClassDesc by class name.
  192.     static TClassDescListByID* fgClassDescListByID;        // List of ClassDesc, indexed by class ID.
  193.     static TClassDescSignatureList* fgSignatures;        // Standard object signatures and their classIDs
  194.     static ClassID fgNextClassID;                        // The next unique class ID.
  195.     
  196. };
  197.  
  198. #if qTheDebugger && PRAGMA_ALIGN_SUPPORTED
  199. #pragma options align=reset
  200. #endif
  201.  
  202. //========================================================================================
  203. // Macros for generating and accessing class information
  204. //========================================================================================
  205.  
  206. #ifndef __UCLASSDESC_PRIVATE__
  207. #include "UClassDesc.Private.h"
  208. #endif
  209.  
  210. // DeclareClassDesc macro: Left for compatibility. Does forward reference of
  211. // class, which can't hurt.
  212.  
  213. #define DeclareClassDesc(name)                                                            \
  214.     class name
  215.  
  216. //----------------------------------------------------------------------------------------
  217. // DeclareClass macro: Declares methods and fields of application class <name> necessary
  218. //                       to access type information for the class. The DeclareClass should
  219. //                       be used once for each application class declaration immediately
  220. //                       following the '{' for the application class <name>.
  221. //
  222. //    class TCommand : public TEvent
  223. //    {
  224. //        MA_DECLARE_CLASS;
  225. //        
  226. //    public:
  227. //        TCommand();
  228. //----------------------------------------------------------------------------------------
  229.  
  230. #define DeclareClass(name)    MA_DECLARE_CLASS
  231.  
  232. #define MA_DECLARE_CLASS                                                                \
  233.   public:                                                                                \
  234.     static const ClassDesc fgClassDesc;                                                    \
  235.     static const MA_ClassReference fgAncestors[];                                        \
  236.     static const ptrdiff_t fgAncestorOffsets[];                                            \
  237.     virtual MA_ClassReference GetClassDescDynamic() const;                                \
  238.     inline static MA_ClassReference GetClassDescStatic() { return &fgClassDesc; }        \
  239.     static void *_DefaultConstructor()
  240.  
  241. //----------------------------------------------------------------------------------------
  242. // DefineClass macro: Defines data and methods necessary for class <name> to access and
  243. //                      implement type information for the class. Should be used once in the
  244. //                      implementation file for <name>.
  245. //
  246. //    #undef Inherited
  247. //    #define Inherited TEvent
  248. //    #pragma segment MACommandNonRes
  249. //    MA_DEFINE_CLASS_M1(TCommand, Inherited);
  250. //----------------------------------------------------------------------------------------
  251.  
  252. #define MA_DEFINE_CLASS_M0(name)                                                        \
  253.     _MA_CLASS_ANCESTORS_IMPLEMENT_M0(name)                                                \
  254.     _MA_DEFINE_CLASSINFO_OBJECT(name)                                                    \
  255.     _MA_DEFINE_CLASS_METHODS(name)
  256.  
  257. #define MA_DEFINE_CLASS_M1(name, ancestor)                                                \
  258.     _MA_CLASS_ANCESTORS_IMPLEMENT_M1(name, ancestor)                                    \
  259.     _MA_DEFINE_CLASSINFO_OBJECT(name)                                                    \
  260.     _MA_DEFINE_CLASS_METHODS(name)
  261.  
  262. #define MA_DEFINE_CLASS_M2(name, ancestor1, ancestor2)                                    \
  263.     _MA_CLASS_ANCESTORS_IMPLEMENT_M2(name, ancestor1, ancestor2)                        \
  264.     _MA_DEFINE_CLASSINFO_OBJECT(name)                                                    \
  265.     _MA_DEFINE_CLASS_METHODS(name)
  266.  
  267. #define MA_DEFINE_CLASS_M3(name, ancestor1, ancestor2, ancestor3)                        \
  268.     _MA_CLASS_ANCESTORS_IMPLEMENT_M3(name, ancestor1, ancestor2, ancestor3)                \
  269.     _MA_DEFINE_CLASSINFO_OBJECT(name)                                                    \
  270.     _MA_DEFINE_CLASS_METHODS(name)
  271.  
  272. #define MA_DEFINE_CLASS_M4(name, ancestor1, ancestor2, ancestor3, ancestor4)            \
  273.     _MA_CLASS_ANCESTORS_IMPLEMENT_M4(name, ancestor1, ancestor2, ancestor3, ancestor4)    \
  274.     _MA_DEFINE_CLASSINFO_OBJECT(name)                                                    \
  275.     _MA_DEFINE_CLASS_METHODS(name)
  276.  
  277. #define DefineClass(name, firstBase)                                                    \
  278.     MA_DEFINE_CLASS_M1(name, firstBase)
  279.  
  280. //----------------------------------------------------------------------------------------
  281. // Class Registry Macros:    Forces the class <name> to be marked active so that the
  282. //                            linker does not dead strip it. Makes it possible for the
  283. //                            class  to be created by name or by signature. 
  284. //----------------------------------------------------------------------------------------
  285.  
  286. #define MA_REGISTER_CLASS(name)                                                         \
  287.     ClassDesc::CallRegisterClass(&name::fgClassDesc, &name::_DefaultConstructor);
  288.  
  289. #define MA_REGISTER_SIGNATURE(name, signature)                                            \
  290.     ClassDesc::CallRegisterClass(&name::fgClassDesc, &name::_DefaultConstructor);        \
  291.     ClassDesc::CallRegisterSignature(&name::fgClassDesc, signature)
  292.  
  293. // macroDontDeadStrip macro: Left for compatibility. 
  294.  
  295. #define macroDontDeadStrip(name)                                                         \
  296.     MA_REGISTER_CLASS(name)
  297.  
  298. //----------------------------------------------------------------------------------------
  299. // Object Member Macro (simulates the pascal Member function). 
  300. //----------------------------------------------------------------------------------------
  301.  
  302. #define MA_MEMBER(object, class) \
  303.     (((object)->GetClassDescDynamic())->DescendsFrom(&class::fgClassDesc))
  304.  
  305. //----------------------------------------------------------------------------------------
  306. // Dynamic Cast Macro
  307. //----------------------------------------------------------------------------------------
  308.  
  309. // The dynamic cast macro checks the object's run time type information to see if it
  310. // actually descends from the class you want to cast it to. If it does, it performs
  311. // the cast, otherwise it returns NULL. 
  312.  
  313. #define MA_DYNAMIC_CAST(T, p) \
  314.     ( (p) ? (T*) (((p)->GetClassDescDynamic())->DynamicCast(p, &(p)->fgClassDesc, &T::fgClassDesc)) : (T*) 0)
  315.  
  316. #endif // __UCLASSDESC__
  317.